package softtech.app.secretcaller;

import java.text.SimpleDateFormat;
import java.util.Date;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.media.AudioManager;
import android.os.Handler;
import android.provider.CallLog;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class ListenerPhoneState extends PhoneStateListener {

	public static Boolean phoneRinging = false;

	public static int mode;

	private int have_in_database = -1;

	public Context context;

	public static String phone_number = "";

	final String TAG = "LISTENER PHONE STATE";

	DatabaseHandler db;

	public static Boolean isInAppDelete = false;

	String lastCallInApp;

	public ListenerPhoneState(Context ctx) {
		context = ctx;
		db = new DatabaseHandler(context);
		lastCallInApp = "";
	}

	public void onCallStateChanged(int state, String incomingNumber) {

		Log.e(TAG, TAG + " so dien thoai=" + incomingNumber);

		// Check Context
		try {
			if (context == null) {
				return;
			}
			if (db == null) {
				db = new DatabaseHandler(context);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		// Check Login
		int id_login = checkLogin();
		if (id_login < 0) {
			return;
		}

		// Save incomming phone
		if (ToolsSaveFile.checkStringNotNull(incomingNumber)
				&& phone_number.equals("")) {
			phone_number = incomingNumber;
		}

		// Check State
		switch (state) {
		case TelephonyManager.CALL_STATE_IDLE:
			Log.d(TAG, "IDLE " + mode);

			if (ToolsSaveFile.checkStringNotNull(phone_number)) {
				SimpleDateFormat sdf = new SimpleDateFormat(
						"yyyy/MM/dd HH:mm:ss", java.util.Locale.getDefault());
				String last_call = sdf.format(new Date());
				if (!last_call.equals(lastCallInApp)) {
					lastCallInApp = last_call;
					DatabaseCall newCall = new DatabaseCall(phone_number, last_call,
							DatabaseCall.OUTGOING);
					try{
						long contact_id = db.getContactIdLikePhoneNumber(phone_number, checkLogin());
						if(contact_id != -1 ){
							newCall.setContact_id(contact_id);
						}
					}catch(Exception e){
						e.printStackTrace();
					}
					
					
					db.addNewCall(newCall);
				}

				updateViewWhenReceiveCall();
			}
			excuteWhenEndCall();

			break;
		case TelephonyManager.CALL_STATE_OFFHOOK:
			Log.d(TAG, "OFFHOOK");
			if (!isInAppDelete) {
				excuteWhenEndCall();
				updateViewWhenReceiveCall();
			}

			break;
		case TelephonyManager.CALL_STATE_RINGING:

			Log.d(TAG, "RINGING");

			excuteWhenRinging(incomingNumber, id_login);

			break;
		}
	}

	/**
	 * Check Login - (-1) : if not login. - id_login : if logged in.
	 */
	int checkLogin() {
		int id = -1;
		ToolsSaveFile tsf = new ToolsSaveFile();

		String id_loggedin = tsf.LoadContentFile(context,
				ConstantsFileName.FILE_ID_LOG_IN);

		if (id_loggedin == null || id_loggedin.equals("")
				|| id_loggedin.length() == 0) {

			id = -1;
		} else {
			try {
				id = Integer.parseInt(id_loggedin);

			} catch (Exception e) {
				id = -1;
				e.printStackTrace();
			}
		}

		return id;
	}

	/**
	 * Delete call in log calls by phone number
	 * 
	 * @param number
	 *            : incomming number phone
	 */
	public void DeleteCallLogByNumber(String number) {
		Log.e(TAG , "delete so =" + number);
		if (isInAppDelete) {
			isInAppDelete = false;
		} else {
			if (!ToolsSaveFile.checkStringNotNull(number, 1)) {
				return;
			}

			if (have_in_database != 1) {
				return;
			} else {
				have_in_database = -1;
			}
		}

		Log.e(TAG, " DELETE PHONE = " + number);
		
		try {
			Thread.sleep(5000);
			String strNumberOne[] = { number };
			Cursor cursor = context.getContentResolver().query(
					CallLog.Calls.CONTENT_URI, null,
					CallLog.Calls.NUMBER + " = ? ", strNumberOne, "");
			boolean bol = cursor.moveToFirst();
			if (bol) {
				do {
					int idOfRowToDelete = cursor.getInt(cursor
							.getColumnIndex(CallLog.Calls._ID));
					context.getContentResolver().delete(
							CallLog.Calls.CONTENT_URI,
							CallLog.Calls._ID + "= ? ",
							new String[] { String.valueOf(idOfRowToDelete) });
				} while (cursor.moveToNext());
			}
		} catch (Exception ex) {
			Log.v("deleteNumber",
					"Exception, unable to remove # from call log: "
							+ ex.toString());
		}

	}

	/**
	 * When have a call , excute this function when end call
	 */
	void excuteWhenEndCall() {
		// Change phone mode to old phone mode
		try {
			if (mode != -1) {
				AudioManager audioManager = (AudioManager) context
						.getApplicationContext().getSystemService(
								Context.AUDIO_SERVICE);

				if (mode == AudioManager.RINGER_MODE_SILENT) {
					if (audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT) {
						mode = audioManager.getRingerMode();
					}
				}

				audioManager.setRingerMode(mode);
				mode = -1;
				System.gc();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		// Delete Callog
		try {

			new Thread() {
				public void run() {
					DeleteCallLogByNumber(phone_number);
					phone_number = "";
				}
			}.start();

		} catch (Exception e) {
			e.printStackTrace();
		}
		phoneRinging = false;
	}

	/**
	 * When have a call , this function will excute when ringing
	 */
	void excuteWhenRinging(String incomingNumber, int id_login) {
		try {
			if (!phoneRinging) {

				phoneRinging = true;

				AudioManager audioManager = (AudioManager) context
						.getApplicationContext().getSystemService(
								Context.AUDIO_SERVICE);

				mode = audioManager.getRingerMode();

				Log.d(TAG, "RINGING " + mode);

				if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT) {

				} else {
					DatabaseContact mContact = db.getContactFromPhoneNumber(
							incomingNumber, id_login);
					if (mContact != null) {
						// change flag
						have_in_database = 1;

						// Check Database
						audioManager
								.setRingerMode(AudioManager.RINGER_MODE_SILENT);

						// int origionalVolume =
						// audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
						audioManager
								.setStreamVolume(
										AudioManager.STREAM_MUSIC,
										audioManager
												.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
										0);

						SimpleDateFormat sdf = new SimpleDateFormat(
								"yyyy/MM/dd HH:mm:ss",
								java.util.Locale.getDefault());
						String last_call = sdf.format(new Date());
						mContact.setLastCall(last_call);
						db.updateContactLastCall(mContact.getPrimaryKey(),
								mContact);
						if (!last_call.equals(lastCallInApp)) {
							lastCallInApp = last_call;
							
							db.addNewCall(new DatabaseCall(mContact
									.getPrimaryKey(),
									mContact.getPhoneNumber(), last_call,
									DatabaseCall.INCOMMING));
						}
						// update contact last call

						// update call history

						new Handler().postDelayed(new Runnable() {

							@Override
							public void run() {
								Intent startMain = new Intent(
										Intent.ACTION_MAIN);
								startMain.addCategory(Intent.CATEGORY_HOME);
								startMain
										.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
								context.startActivity(startMain);
							}
						}, 2000);
					} else {
						if (isInAppDelete) {
							// Check Database
							audioManager
									.setRingerMode(AudioManager.RINGER_MODE_SILENT);

							// int origionalVolume =
							// audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
							audioManager
									.setStreamVolume(
											AudioManager.STREAM_MUSIC,
											audioManager
													.getStreamMaxVolume(AudioManager.STREAM_MUSIC),
											0);
						}
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	void updateViewWhenReceiveCall() {
		Intent intent_call = new Intent(ConstantsFileName.TAG_BROADCAST);
		intent_call.putExtra(ConstantsFileName.TAG_GET_FLAG,
				ConstantsFileName.FLAG_RECEIVE_CALL);
		context.sendBroadcast(intent_call);
	}
	
}
